﻿using SuperWebSocket;
using System; 
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace SuperWebSocketServerTest
{
    public partial class SocketServer : Form
    {
        bool tempSaveImage = false;

        ProgressBarForm ProgressBar = null;

        OpenFileDialog openfile = new OpenFileDialog();
        SuperWebSocketServer server = new SuperWebSocketServer();

        public SocketServer()
        {
            InitializeComponent();
            InitializeControls();
        }

        protected override void OnClosed(EventArgs e)
        {
            server.Close();
            base.OnClosed(e);           
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
        }

        private void InitializeControls()
        {
            this.txtIpAddress.Text = server.Configure.IPAddress.ToString();
            this.txtPort.Text = server.Configure.Port.ToString();

            server.OnStarted += new WebSocketEventHandler(OnServerStarted);
            server.OnLogined += new WebSocketEventHandler(OnClientLogined);
            server.OnLogout += new WebSocketEventHandler(OnClientLogout);           
            server.OnMessage += new WebSocketEventHandler(OnReceiveMessage);
            server.OnImage += new WebSocketEventHandler(OnReceiveImage);
            server.OnClosed += new WebSocketEventHandler(OnServerClosed);
            server.OnError += new WebSocketEventHandler(OnServerError);
            server.OnStoped += new WebSocketEventHandler(OnServerStoped);

            //发送文件
            server.OnBeinSendFile += new WebSocketEventHandler(OnBeinSendFile);
            server.OnReportSendFile += new WebSocketProgressEventHandler(OnReportSendFile);
            server.OnFinishSendFile += new WebSocketEventHandler(OnFinishSendFile);
           
        }

        private void Message(DateTime Datetime, string Message)
        {
            if (this.MsgBox.InvokeRequired)
            {
                try
                {
                    this.MsgBox.Invoke(new MethodInvoker(delegate()
                    {
                        this.MsgBox.AppendText(Datetime.ToString("yyyy-MM-dd HH:mm:ss") + " " + Message + Environment.NewLine);
                    }));
                }
                catch
                {
                    //this.MsgBox.AppendText(Datetime.ToString("yyyy-MM-dd HH:mm:ss") + " " + Message + Environment.NewLine);
                }
            }
            else
            {
                this.MsgBox.AppendText(Datetime.ToString("yyyy-MM-dd HH:mm:ss") + " " + Message + Environment.NewLine);
            }
        }

        private void Send()
        {
            int index = 0;
            string Message = this.txtSendContent.Text.Trim();
            for (; index < this.userList.Items.Count; index++)
            {
                if (this.userList.GetSelected(index))
                    server.SendMessage(((WebSocketSession)this.userList.Items[index]).Id, Message);
            }
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            if (server.State != WebSocketServerState.Started)
                server.Start();
            else
                server.Stop();
        }

        private bool OnServerStarted(object sender, WebSocketEventArgs e)
        {
            btnConnect.Invoke(new MethodInvoker(delegate() { btnConnect.Text = "停止"; }));
            Message(e.DateTime, "服务：" + server.Name + "(IP地址：" + server.Configure.IPAddress + ",端口：" + server.Configure.Port + ")已开启监听...");
            return false; 
        }

        private bool OnClientLogined(object sender,WebSocketEventArgs e)
        {
            var clientSession = ((WebSocketClient)sender).Session;
            this.userList.Invoke(new MethodInvoker(delegate() { this.userList.Items.Add(clientSession); }));
            return false;
        }

        private bool OnReceiveMessage(object sender, WebSocketEventArgs e)
        {
            var data = (WebSocketContextData)e.Data;
            Message(e.DateTime, data.SendId + " 对 " + data.ReceiveId + " 说：" + data.Data);
            return false;
        }

        private bool OnReceiveImage(object sender, WebSocketEventArgs e)
        {
            var data = (WebSocketContextData)e.Data;
            WebSocketImageData wsImageData = (WebSocketImageData)data.Data;

            if (tempSaveImage)
            {
                byte[] DataBuffer = (byte[])wsImageData.Data;
                string temp = AppDomain.CurrentDomain.BaseDirectory + "temp/";

                if (!new System.IO.DirectoryInfo(temp).Exists)
                    System.IO.Directory.CreateDirectory(temp);

                using (System.IO.FileStream stream = new System.IO.FileStream(temp + wsImageData.Name + "." + wsImageData.Format, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
                {
                    stream.Write(DataBuffer, 0, DataBuffer.Length);
                }
            }           

            Message(e.DateTime, data.SendId + " 对 " + data.ReceiveId + " 传送图片: " + wsImageData.Name + "." + wsImageData.Format + " 大小：" + wsImageData.ImageSize);

            return false;
        }

        private bool OnClientLogout(object sender, WebSocketEventArgs e)
        {
            var clientSession = ((WebSocketClient)sender).Session;
            this.userList.Invoke(new MethodInvoker(delegate()
            {
                foreach (WebSocketClientSession session in this.userList.Items)
                {
                    if (session.Id == clientSession.Id)
                    {
                        this.userList.Items.Remove(session);
                        break;
                    }
                }
            })); 
            return false;
        }

        private bool OnServerError(object sender, WebSocketEventArgs e)
        {
            if (server.State != WebSocketServerState.Disposed)
                Message(e.DateTime, e.Message);
            return false;
        }

        private bool OnServerClosed(object sender, WebSocketEventArgs e)
        {            
            return false;
        }

        private bool OnBeinSendFile(object sender, WebSocketEventArgs e)
        {
            WebSocketFileData wsFileData = (WebSocketFileData)e.Data;

            string Name = wsFileData.Name + wsFileData.Format;
            string Describtion = "发送中";

             this.Invoke(new MethodInvoker(()=>{

                 ProgressBar = new ProgressBarForm(Name, Describtion);
                 ProgressBar.Show();
                 ProgressBar.Location = new Point(this.Left + (this.Width - ProgressBar.Width) / 2, this.Top + (this.Height - ProgressBar.Height) / 2);
                 ProgressBar.BringToFront();

             }));

            return false;
        }

        private void OnReportSendFile(object sender, WebSocketProgressEventArgs e)
        {
            this.Invoke(new MethodInvoker(() =>
            {
                ProgressBar.ReportProgressValue(e.Total, e.Value, e.Precent);
            }));
        }

        private bool OnFinishSendFile(object sender, WebSocketEventArgs e)
        {
            return false;
        }

        private bool OnServerStoped(object sender, WebSocketEventArgs e)
        {
            var WebSocketServer = ((WebSocketServer)sender);
            var times = WebSocketServer.Session.AliveDateTimes / 1000;

            //times = 12 * 60 * 60 * 24 * 7 * 5 * 12+ 60 * 60 * 24 * 7 * 5 * 6;

            var AliveTimes = " " + (times).ToString("N1") + " 秒";
            if (times > 60 * 60 * 24 * 7 * 5 * 12)
                AliveTimes = " " + (times / 60 / 60 / 24 / 7 / 5 / 12).ToString("N1") + " 年";
            else if (times > 60 * 60 * 24 * 7 * 5)
                AliveTimes = " " + (times / 60 / 60 / 24 / 7 / 5).ToString("N1") + " 月";
            else if (times > 60 * 60 * 24 * 7)
                AliveTimes = " " + (times / 60 / 60 / 24 / 7).ToString("N1") + " 周";
            else if (times > 60 * 60 * 24)
                AliveTimes = " " + (times / 60 / 60 / 24).ToString("N1") + " 天";
            else if (times > 60 * 60)
                AliveTimes = " " + (times / 60 / 60).ToString("N1") + " 小时";
            else if (times > 60)
                AliveTimes = " " + (times / 60).ToString("N1") + " 分钟";

            btnConnect.Invoke(new MethodInvoker(delegate () { btnConnect.Text = "开启"; }));
            Message(Convert.ToDateTime(e.DateTime), "服务：" + WebSocketServer.Name + "(IP地址：" + WebSocketServer.Configure.IPAddress + ",端口：" + WebSocketServer.Configure.Port + ")运行了" + AliveTimes + ",现已停止");
            return false;
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            Send();
        }

        private void 发送图片ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openfile.Filter = "jpg|*.jpg|png|*.png";
            if (openfile.ShowDialog(this).Equals(DialogResult.OK))
            {
                if (string.IsNullOrEmpty(openfile.FileName))
                    return;

                byte[] imageBuffer = null;
                System.IO.FileInfo fi = new System.IO.FileInfo(openfile.FileName);
                using (System.IO.FileStream filestream = new System.IO.FileStream(fi.FullName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                {
                    imageBuffer = new byte[filestream.Length];
                    filestream.Read(imageBuffer, 0, imageBuffer.Length);
                }               

                string fileName = fi.Name;
                fileName = fileName.Substring(0, fileName.LastIndexOf('.'));
                string fileExtension = fi.Extension;
                fileExtension = fileExtension.Substring(1).ToLower().Trim();

                int index = 0;
                for (; index < this.userList.Items.Count; index++)
                {
                    if (this.userList.GetSelected(index))
                    {
                        string Id = ((WebSocketSession)this.userList.Items[index]).Id;
                        server.SendImage(Id, fileName, fileExtension, imageBuffer);
                        this.Message(DateTime.Now, "你 对 " + Id + " 发送图片：" + fileName + "." + fileExtension + " 大小：" + server.GetBytesSize(imageBuffer.Length));
                    }
                }
            }
        }

        private void 发送文件ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openfile.Filter = "所有文件|*.*";
            if (openfile.ShowDialog(this).Equals(DialogResult.OK))
            {
                if (string.IsNullOrEmpty(openfile.FileName))
                    return;

                System.IO.FileInfo fi = new System.IO.FileInfo(openfile.FileName);             

                string fileName = fi.Name;
                fileName = fileName.Substring(0, fileName.LastIndexOf('.'));
                string fileExtension = fi.Extension;
                fileExtension = fileExtension.Substring(1).ToLower().Trim();                

                int index = 0;
                for (; index < this.userList.Items.Count; index++)
                {
                    if (this.userList.GetSelected(index))
                    {
                        string Id = ((WebSocketSession)this.userList.Items[index]).Id;
                        server.SendFile(Id, fileName, fileExtension, fi.FullName);
                        this.Message(DateTime.Now, "你 对 " + Id + " 发送文件：" + fileName + "." + fileExtension + " 大小：" + server.GetBytesSize(fi.Length));
                    }
                }
            }
        }
    }
}
